package im

import (
    "time"
	"errors"
	"strings"
	"strconv"
	"encoding/json"
	"dhfshop/models/im"
	"dhfshop/domain/im"
	"dhfshop/controllers/base"
	"github.com/astaxie/beego"
	"dhfshop/models/org"
	"github.com/astaxie/beego/validation"
	//"github.com/astaxie/beego/orm"
	"dhfshop/domain/nsqproc"
)

type ChatRecordController struct {
	base.BaseController
}

// fields: col1,col2,entity.col3; query: k:v,k:v; order_by: k:v,k:v
func (this *ChatRecordController) GetChatRecordPara()(bool,map[string]string,[]string,map[string]string,int,int,error) {
	query := make(map[string]string)
	fields := []string{}
	order_by := make(map[string]string)
	offset := 0     //default is 0
	limit := 10    //default is 50
	v := struct {
	    Fields       string     `form:"fields"`
		Query        string     `form:"query"`
		OrderBy      string     `form:"order_by"`
		PageSize     int        `form:"page_size"`
		PageNo       int        `form:"page_no"`
		IsRead       bool       `form:"is_read"`
	}{PageSize:10, PageNo:1, IsRead:false}     
	this.ParseForm(&v)
	valid := validation.Validation{}
	valid.Range(v.PageSize,1,1000,"page_size")
	valid.Range(v.PageNo,1,1000,"page_no")
	passed, _ := valid.Valid(&v)
	if !passed {
		err := errors.New(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return v.IsRead,query,fields,order_by,offset,limit,err
	}
	v.PageNo = v.PageNo - 1     //为了计算offset
    if len(v.Fields) > 2 {
	    fields = strings.Split(v.Fields, ",")
	}
    if len(v.Query) > 2 {
	    for _, cond := range strings.Split(v.Query, ",") {
	        kv := strings.Split(cond, ":")
	        if len(kv) != 2 {
	            err := errors.New("Error: invalid query key/value pair")
	            return v.IsRead,query,fields,order_by,offset,limit,err
	        }
	        k, v := kv[0], kv[1]
	        query[k] = v
	    }
	}
    if len(v.OrderBy) > 2 {
	    for _, cond := range strings.Split(v.OrderBy, ",") {
	        kv := strings.Split(cond, ":")
	        if len(kv) != 2 {
	            err := errors.New("Error: invalid order_by key/value pair")
	            return v.IsRead,query,fields,order_by,offset,limit,err
	        }
	        k, v := kv[0], kv[1]
	        order_by[k] = v
	    }
	}
	offset = v.PageNo*v.PageSize
	limit = v.PageSize
	return v.IsRead,query,fields,order_by,offset,limit,nil
}

func (this *ChatRecordController) List() {
	isRead,query,fields,order_by,offset,limit,err := this.GetChatRecordPara()
	if err != nil {
	   this.ServeError(err.Error())
	   return
	}
	partnerId := int64(this.Ctx.Input.GetData("curCompanyId").(int))
	query["partner_id"] = strconv.FormatInt(partnerId, 10)
	list, cnt, err := im.GetAllChatRecords(query,fields,order_by,offset,limit)
	if err != nil {
	    this.ServeError(err.Error())
		return
	}
	//beego.Debug("ChatRecord Get:", isRead, query, list)
	if !isRead {
	    rsp := struct {
			TotalCount    int64            `json:"total_count"`
			ChatRecords   []*im.ChatRecord `json:"chat_records"`
		}{TotalCount: cnt, ChatRecords: list}
		this.Data["json"] = rsp
		this.ServeJSON()
	    return
	}
	for _, message := range list {
		if chatSession, err := im.GetChatSessionByMemberOpenId(message.MemberOpenId); err == nil {
		    // 已读消息，跳过
			if message.StatusId == 2 {
			   continue
			}
			chatSession.AgentOpenId = this.CurrentUser.OpenId
			chatSession.StatusId = 1
			chatSession.IsRead = 2
			im.UpdateChatSessionById(chatSession, "agent_open_id", "status_id", "is_read")
		    // 策略：客服发送的消息不改Open_Id, 顾客未读消息改客服的open_id
			// 客服发送的消息,不更改agent_open_id
			if message.SendBy == 2 {
			   message.StatusId = 2
			   message.ChatSessionId = chatSession.ChatSessionId
			   im.UpdateChatRecordById(message, "chat_session_id", "status_id")
			}else{
			   message.StatusId = 2
			   message.ChatSessionId = chatSession.ChatSessionId
			   message.AgentOpenId = this.CurrentUser.OpenId
			   im.UpdateChatRecordById(message, "chat_session_id", "agent_open_id", "status_id")
			}
		}
	}
	rsp := struct {
		TotalCount    int64            `json:"total_count"`
	    ChatRecords   []*im.ChatRecord `json:"chat_records"`
	}{TotalCount: cnt, ChatRecords: list}
	this.Data["json"] = rsp
	this.ServeJSON()
}

func (this *ChatRecordController) Post() {
	var v im.ChatRecord
	this.ParseForm(&v)
	valid := validation.Validation{}
	valid.Required(v.AppId, "app_id")
	valid.Required(v.MemberOpenId, "member_open_id")
	//valid.Required(v.AgentOpenId, "agent_open_id")
	passed, _ := valid.Valid(&v)
	if !passed {
		this.ServeError(valid.Errors[0].Key+" "+valid.Errors[0].Message)
		return
	}
	v.PartnerId = int64(this.Ctx.Input.GetData("curCompanyId").(int))
	curUserId := int64(this.Ctx.Input.GetData("curUserId").(int))
	chatSession, err := im.GetChatSessionByMemberOpenId(v.MemberOpenId)
	if err != nil {
	    this.ServeError("找不到用户信息")
		return 
	}
	v.ChatSessionId = chatSession.ChatSessionId
	agentUser, err := org.GetUserByUserId(curUserId)
	if err != nil {
	    this.ServeError("找不到用户信息")
		return 
	}
	v.AgentOpenId = agentUser.OpenID
	//beego.Debug("v.AgentOpenId:", v.AgentOpenId)
	if len(v.MsgBody) > 3 {
	    if v.MsgType == "text" {
		    body := struct {
				Content string `json:"content"` 
			}{}
			if err := json.Unmarshal([]byte(v.MsgBody), &body); err == nil {
				v.Content = body.Content 
			}
		} else if v.MsgType == "image" {
			body := struct {
				MediaId string `json:"media_id"`
			}{}
			if err := json.Unmarshal([]byte(v.MsgBody), &body); err == nil {
				v.MediaId = body.MediaId 
			}
		} else if v.MsgType == "link" {
		    v.Link = v.MsgBody
		} else if v.MsgType == "miniprogrampage" {
		
		} else {
		
		}
	}
	v.StatusId = 2
	err = imlayer.SendCustomerMessage(chatSession.AppId,v.MemberOpenId,v.MsgType,v.MsgBody)      //给客户回复消息
	if err != nil {
	    this.ServeError(err.Error())
		return 
	}
	v.ChatRecordId, err = im.AddChatRecord(&v)
	if err != nil {
	    this.ServeError(err.Error())
		return 
	}
	if len(v.FormId) > 0 {
	    if v.FormId == "undefined" {
		
		}else if v.FormId == "the formId is a mock one" {
		
		}else{
			formIdCache := &im.FormIdCache{PartnerId:v.PartnerId,MemberId:curUserId,AppId:chatSession.AppId,
	                  FormId:v.FormId,OpenId:v.AgentOpenId,Types:"chat",Xid:"",
					  MaxCount:1,ExpireAt:time.Now().UTC().Add(time.Hour*24*7)}
			if id, err := im.AddFormIdCache(formIdCache); err == nil {
			    beego.Debug("ChatRecordController AddFormIdCache:", id)
			}
			nsqproc.DelFormIdExpiredTask(0)
		}
	}
	this.Data["json"] = v
	this.ServeJSON()
}

